#ifndef __3DS_LOADER_H__
#define __3DS_LOADER_H__

namespace Venus
{
	namespace Graphics
	{		
		//>------ Id Chunk

		//----------------- MAIN3DS -----------------
		// Description: Main chunk, contains all the other chunks
		// Chunk ID: 0x4d4d 
		// Chunk Lenght: 0 + sub chunks
		//-------------------------------------------
		#define MAIN3DS       0x4D4D

		//>------ Main Chunks

		//----------------- EDIT3DS -----------------
		// Description: 3D Editor chunk, objects layout info 
		// Chunk ID: 0x3d3d
		// Chunk Lenght: 0 + sub chunks
		//-------------------------------------------
		#define EDIT3DS       0x3D3D  // this is the start of the editor config

		#define KEYF3DS       0xB000  // this is the start of the keyframer config

		//>------ sub defines of EDIT3DS

		#define EDIT_MATERIAL 0xAFFF
		#define EDIT_CONFIG1  0x0100
		#define EDIT_CONFIG2  0x3E3D
		#define EDIT_VIEW_P1  0x7012
		#define EDIT_VIEW_P2  0x7011
		#define EDIT_VIEW_P3  0x7020
		#define EDIT_VIEW1    0x7001
		#define EDIT_BACKGR   0x1200
		#define EDIT_AMBIENT  0x2100

		//--------------- EDIT_OBJECT ---------------
		// Description: Object block, info for each object
		// Chunk ID: 0x4000
		// Chunk Lenght: len(object name) + sub chunks
		//-------------------------------------------
		#define EDIT_OBJECT   0x4000

		#define EDIT_UNKNW01  0x1100
		#define EDIT_UNKNW02  0x1201
		#define EDIT_UNKNW03  0x1300
		#define EDIT_UNKNW04  0x1400
		#define EDIT_UNKNW05  0x1420
		#define EDIT_UNKNW06  0x1450
		#define EDIT_UNKNW07  0x1500
		#define EDIT_UNKNW08  0x2200
		#define EDIT_UNKNW09  0x2201
		#define EDIT_UNKNW10  0x2210
		#define EDIT_UNKNW11  0x2300
		#define EDIT_UNKNW12  0x2302 // new chunk type
		#define EDIT_UNKNW13  0x3000
		#define EDIT_UNKNW14  0xAFFF

		//>------ sub defines of EDIT_MATERIAL
		#define MAT_NAME01    0xA000  //> includes name (see mli doc for materials)

		//>------ sub defines of EDIT_OBJECT

		//--------------- OBJ_TRIMESH ---------------
		// Description: Triangular mesh, contains chunks for 3d mesh info
		// Chunk ID: 0x4100
		// Chunk Lenght: 0 + sub chunks
		//-------------------------------------------
		#define OBJ_TRIMESH   0x4100
		#define OBJ_LIGHT     0x4600
		#define OBJ_CAMERA    0x4700

		#define OBJ_UNKNWN01  0x4010
		#define OBJ_UNKNWN02  0x4012 //>>---- Could be shadow

		//>------ sub defines of OBJ_CAMERA
		#define CAM_UNKNWN01  0x4710 // new chunk type
		#define CAM_UNKNWN02  0x4720 // new chunk type

		//>------ sub defines of OBJ_LIGHT
		#define LIT_OFF       0x4620
		#define LIT_SPOT      0x4610
		#define LIT_UNKNWN01  0x465A

		//>------ sub defines of OBJ_TRIMESH

		//--------------- TRI_VERTEXL ---------------
		// Description: Vertices list
		// Chunk ID: 0x4110
		// Chunk Lenght: 1 x unsigned short (number of vertices) 
		//             + 3 x float (vertex coordinates) x (number of vertices)
		//             + sub chunks
		//-------------------------------------------
		#define TRI_VERTEXL   0x4110

		#define TRI_FACEL2    0x4111 // unknown yet

		//--------------- TRI_FACEL1 ----------------
		// Description: Polygons (faces) list
		// Chunk ID: 0x4120
		// Chunk Lenght: 1 x unsigned short (number of polygons) 
		//             + 3 x unsigned short (polygon points) x (number of polygons)
		//             + sub chunks
		//-------------------------------------------
		#define TRI_FACEL1    0x4120

		//------------- TRI_MAPPINGCOORS ------------
		// Description: Vertices list
		// Chunk ID: 0x4140
		// Chunk Lenght: 1 x unsigned short (number of mapping points) 
		//             + 2 x float (mapping coordinates) x (number of mapping points)
		//             + sub chunks
		//-------------------------------------------
		#define TRI_MAPPINGCOORS 0x4140

		#define TRI_SMOOTH    0x4150
		#define TRI_LOCAL     0x4160
		#define TRI_VISIBLE   0x4165

		//>>------ sub defs of KEYF3DS
		#define KEYF_UNKNWN01 0xB009
		#define KEYF_UNKNWN02 0xB00A
		#define KEYF_FRAMES   0xB008
		#define KEYF_OBJDES   0xB002

		#define KEYF_OBJHIERARCH  0xB010
		#define KEYF_OBJDUMMYNAME 0xB011
		#define KEYF_OBJUNKNWN01  0xB013
		#define KEYF_OBJUNKNWN02  0xB014
		#define KEYF_OBJUNKNWN03  0xB015  
		#define KEYF_OBJPIVOT     0xB020  
		#define KEYF_OBJUNKNWN04  0xB021  
		#define KEYF_OBJUNKNWN05  0xB022  

		//>>------  these define the different color chunk types
		#define COL_RGB  0x0010
		#define COL_TRU  0x0011
		#define COL_UNK  0x0013 // unknown

		//>>------ defines for viewport chunks

		#define TOP           0x0001
		#define BOTTOM        0x0002
		#define LEFT          0x0003
		#define RIGHT         0x0004
		#define FRONT         0x0005
		#define BACK          0x0006
		#define USER          0x0007
		#define CAMERA        0x0008 // 0xFFFF is the code read from file
		#define LIGHT         0x0009
		#define DISABLED      0x0010
		#define BOGUS         0x0011

		class TriDSLoader
		{
		public:
			TriDSLoader()
				: m_Verts( NULL ), m_TCoords( NULL ),
				m_Faces( NULL ), m_NrVerts( 0 ), 
				m_NrFaces( 0 ), m_NrTCoords( 0 ) { }

			~TriDSLoader();

			bool Load( const char* a_File );

			Mesh* GetMesh( Material* a_Mat = NULL );

		protected:
			void ReadVertexChunk( FILE* fd );

			void ReadFaceChunk( FILE* fd );

			void ReadMappingCoordsChunk( FILE* fd );

			void ReadMaterialChunk( FILE* fd );

		private:
			// variables for the 3ds loader
			float* m_Verts, *m_TCoords;

			uint16 m_NrVerts, m_NrFaces, m_NrTCoords;

			uint16* m_Faces;

			char _objName[ 20 ];
		};
	}
}

#endif//__3DS_LOADER_H__
